package org.gruposp2p.dnie.service.jpa;

import java.util.Collection;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.gruposp2p.dnie.model.DNIeDocumentToSign;
import org.gruposp2p.dnie.model.DNIeSignedDocument;
import org.gruposp2p.dnie.model.DNIeSignedDocumentComment;
import org.gruposp2p.dnie.model.DNIeSignedDocumentOptionSelected;
import org.gruposp2p.dnie.model.DNIeUser;
import org.gruposp2p.dnie.service.DNIeSignedDocumentDAO;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.annotation.Propagation;

/**
 *
 * @author jj
 */
@Repository("signedDocumentDao")
public class JpaDNIeSignedDocumentDAO implements DNIeSignedDocumentDAO {

    private EntityManager entityManager;

    @PersistenceContext
    public void setEntityManager(EntityManager entityManager) {
            this.entityManager = entityManager;
    }

    public DNIeSignedDocument findById(Integer id) {
        return entityManager.find(DNIeSignedDocument.class, id);
    }

    @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
    public List<DNIeSignedDocument> findList(
    		DNIeDocumentToSign documentToSign, int firstResult, int maxResults) {
        Query query = entityManager.createQuery(
                "SELECT d FROM DNIeSignedDocument d WHERE d.dnieDocumentToSignId = :dnieDocumentToSignId ORDER BY date DESC");
        query.setParameter("dnieDocumentToSignId", documentToSign); 
        query.setFirstResult(firstResult);
        query.setMaxResults(maxResults);
        List<DNIeSignedDocument> signedDocuments = query.getResultList();
        return signedDocuments;
    }

    @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
    public List<DNIeSignedDocument> findUserList(
    		int firstResult, int maxResults, DNIeUser dnieUserId) {
        Query query = entityManager.createQuery(
                "SELECT d FROM DNIeSignedDocument d WHERE d.dnieUserId = :dnieUserId ORDER BY date DESC");
        query.setParameter("dnieUserId", dnieUserId);
        query.setFirstResult(firstResult);
        query.setMaxResults(maxResults);
        List<DNIeSignedDocument> signedDocuments = query.getResultList();
        return signedDocuments;
    }
    
    @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
    public DNIeSignedDocument save(DNIeSignedDocument signedDocument) {
        Collection<DNIeSignedDocumentOptionSelected> options =
                signedDocument.getDNIeSignedDocumentOptionSelectedCollection();
    	if (options != null) {
            for (DNIeSignedDocumentOptionSelected option : options) {
                option.setDnieSignedDocumentId(signedDocument);
            }
    	}
        Collection<DNIeSignedDocumentComment> comments =
                signedDocument.getDNIeSignedDocumentCommentCollection();
    	if (comments != null) {
            for (DNIeSignedDocumentComment comment : comments) {
                comment.setDNIeSignedDocumentId(signedDocument);
                comment.setDNIeUserId(signedDocument.getDnieUserId());
            }
    	}
        entityManager.persist(signedDocument);
        entityManager.flush();
        return signedDocument;
    }

    @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
    public DNIeSignedDocument update(DNIeSignedDocument signedDocument) {
        Collection<DNIeSignedDocumentComment> comments =
                signedDocument.getDNIeSignedDocumentCommentCollection();
    	if (comments != null) {
            for (DNIeSignedDocumentComment comment : comments) {
                comment.setDNIeSignedDocumentId(signedDocument);
            }
    	}
        Collection<DNIeSignedDocumentOptionSelected> options =
                signedDocument.getDNIeSignedDocumentOptionSelectedCollection();
    	if (options != null) {
            for (DNIeSignedDocumentOptionSelected option : options) {
                option.setDnieSignedDocumentId(signedDocument);
            }
    	}
        entityManager.merge(signedDocument);
        entityManager.flush();
        return signedDocument;
    }

    @Transactional(readOnly=false, propagation=Propagation.REQUIRED)
    public boolean delete(Integer documentId) {
        DNIeSignedDocument dnieSignedDocument = entityManager.getReference(
                DNIeSignedDocument.class, documentId);
        if (dnieSignedDocument == null)
                return false;
        entityManager.remove(dnieSignedDocument);
        entityManager.flush();
        return true;
    }

    public DNIeSignedDocument findByUserAndDocumentToSign(
    		DNIeUser dnieUserId, DNIeDocumentToSign dnieDocumentToSignId) {
    	DNIeSignedDocument result = null;
        Query query = entityManager.createQuery(
                "SELECT d FROM DNIeSignedDocument d WHERE d.dnieUserId = :dnieUserId AND d.dnieDocumentToSignId = :dnieDocumentToSignId");
        query.setParameter("dnieUserId", dnieUserId);
        query.setParameter("dnieDocumentToSignId", dnieDocumentToSignId); 
        List<DNIeSignedDocument> signedDocuments = query.getResultList();
        if (!signedDocuments.isEmpty()) result = signedDocuments.iterator().next();
        return result;
    }

    public int getNumberOfSignedItems(DNIeDocumentToSign dnieDocumentToSignId) {
        Query query =entityManager.createQuery(
                "SELECT COUNT(d.id) FROM DNIeSignedDocument d WHERE d.dnieDocumentToSignId = :dnieDocumentToSignId");
        query.setParameter("dnieDocumentToSignId", dnieDocumentToSignId);
        Number countResult = (Number) query.getSingleResult();
        return countResult.intValue();
    }

}